#ifndef MOF_PROTOCOL_H
#define MOF_PROTOCOL_H

#include <QObject>
#include <mutex>

#include "def_struct.h"
#include "def_enum.h"

#include "commsignalslot.h"

struct QUEUE_PARA
{
    char data[1024*2];
    int  offset;
};

struct PRO_PARA
{
    int   login_status;          // 登录状态标识 0:未登录（初始化状态）；1:登录成功
    int   protool_status;        // 协议状态标识 0:初始化；1:重新登录；2:退出
    int   heart_interval;        // 心跳间隔
    long  heart_time;            // 当前心跳时间

    int   link_status;           // 连接/接入状态标识 0:未连接（初始化状态）；1:连接成功
    int   link_port;             // 连接/接入服务器端口
    char  link_server[16];       // 连接/接入服务器IP
    char  link_tocken[32];       //
    char  link_plugin_id[32];    //

    struct CONFIG_PARA
    {
        char  pin_code[64];
        char  sn_code[128];
        char  protool_key[32];
        char  login_server[32];  // 登录服务器IP
        char  login_port[16];    // 登录服务器端口
    } conf; // 配置文件参数
};


#define DX_MAGIC_HEAD 0xddcc
#define APP_DEV "Dev"
#define APP_DEV_PIN "PIN"

#define APP_PORTOOL "Protool"
#define APP_PORTOOL_KEY "KEY"
#define APP_PORTOOL_SERVER "SERVER"
#define APP_PORTOOL_PORT "PORT"

#define KEY_PIN APP_DEV_PIN
#define KEY_KEY APP_PORTOOL_KEY
#define KEY_SERVER APP_PORTOOL_SERVER
#define KEY_PORT APP_PORTOOL_PORT

#define DEF_EMPTY       ""
#define DEF_SERVER_IP   "171.208.222.113" // 测试环境IP
#define DEF_SERVER_PORT "6037"            // 测试环境PORT

#define PACKAGE_HEAD_LENGTH 3
#define DATA_HEAD_LENGTH 4
#define PACKAGE_SEQ_LENGTH 2
#define PACKAGE_DATA_LENGTH 2
#define LOGIN_OPT_LENGTH 15
#define LINK_OPT_LENGTH 44
#define ACK_YES 1
#define ACK_NO 0


class mof_protocol : public QObject
{
    Q_OBJECT
public:
    mof_protocol(QObject *parent = nullptr);

    static mof_protocol* Instance();

    int push(char *buff, int length);
    int popup(PACKAGE_HEAD* phead, DATA_HEAD *dhead, char* optbuff, char *buff, short* seq);

    void run();
    void mof_pharse();
    void upData();

signals:
    void mofSignalLog(CommSignalSlot::logType, const QString&, const QString&);

private:
    std::mutex _mutex;
    struct QUEUE_PARA queue_para;
    struct PRO_PARA pro_para;

    time_t opt_time;
    char enc_s_buf[256];

    void init_protocol();
    void read_conf();
    int get_key_value_str(const char *, const char *, char *, unsigned int);
    unsigned char get_check_sum(unsigned char *pack, int pack_len);

    int mof_recv_parse(PACKAGE_HEAD phead, DATA_HEAD dhead, char *optbuff, char *buff, short seq);

    int mof_crypt(char *enc_s_buf, char *encbuf, int *Number, int *Total, int Len);
    int aes_decrypt(char* enckey, char* encbuf, char* decbuf, int inlen, int* outlen);
    int aes_encrypt(char* enckey, char* encbuf, char* decbuf, int inlen, int* outlen);

    int send_up_data(unsigned char *optdata, unsigned char *data, PACKAGE_TYPE type, int isack, int optlen, int len, U8 checks);

    int send_business_up_data(void *data, int len);
    int send_management_up_data(void *data, int len);
    int send_business_ack_data(short errcode, unsigned char *buff, int len);
    int send_management_ack_data(short errcode, unsigned char *buff, int len);
    int dev_data_down(const char *data, int data_len);

    int login_service();
    int link_service();
    int heart_beep();
    int dev_version_report();
};

#endif // MOF_PROTOCOL_H
